/********************************************************
* @file: GenExactCurve.cpp (v3.81)
* @date: 15/06/2012
* @author: Ricardo C. Marques
**********************************************************/
/*

** CLASS DESCRIPTION
GenExactCurve is an abstract class created to standardize the
public methods of its subclasses(CrvOnSurf, SurfPlaneCrv,
SurfSurfCrv, PrjCrvOnSurf, etc). GenExactCurve also offers to
its subclasses some basic methods to build polylines and to
perform topological attractions. Its subclasses destructors 
are responsible for destroying the created curves, by calling
KillCurves. The curves construction is done automatically in
the methods: CreateFirstCurve, AddCurvePoint, etc.
GenExactCurve stands for "Generic Exact Curve". 
This class cannot be instantiated.

*/
#ifndef _GENEXACTCURVE_HPP
#define _GENEXACTCURVE_HPP

/* Geometry and Topology Header Files */
#include "geom/point3d.h"

/* Constants Definitions */
/* Markers:
All SearchIntersections methods in ExactCurves package will 
need markers. They classify a mesh primitive (node/edge/elem)
according to a visiting status.
*/
#define NOT_VISITED   0 // Primitive has not been visited yet
#define VISITED       1 // Primitive has already been visited
#define REVISIT       2 // Primitive needs to be revisited 
                        // (in case of creating a closed polyline)
#define IGNORED       3 // Primitive must not be visited 
#define SKIRTED       4 // Search will go round this primitive
                        // (in case of a hole in the surface)


/* Abstract Class Generic Exact Curve */
class GenExactCurve
{
  /* Constructor/Destructor */
public: 
  GenExactCurve();
  virtual ~GenExactCurve();

  /* Client Methods:                   */
  /* Methods for iterating over curves */
public:
  // Returns the number of Curves created
  size_t getNumberOfCurves();

  // Returns number of points in the current curve
  // Must be called always after GetFrstCurve or GetNextCurve
  size_t getCurveSize();    

  // Returns pointer to the first curve
  Point3D* getFrstCurve();

  // Returns pointer to the next curve or NULL 
  // in case a next curve does not exist.
  Point3D* getNextCurve();  

  /* Methods for curves building */
protected:
  void CreateFirstCurve();
  void AddCurvePoint( double _Point[3] );
  void StartInvertedSection();
  void EndInvertedSection();
  void CreateNewCurve(bool IsInverted=false);
  void CloseCurrentCurve();
  void EndCreatingCurves();
  void FilterCurves();
  void KillCurves();
  virtual void BuildCurves()=NULL;// Must start calling
  // CreateFirstCurve and
  // finish calling
  // EndCreatingCurves
private:
  bool CheckCurveLoops(  size_t curveSize, Point3D* curve, double* curveLength, double* smallestSeg);
  void FilterCurve    (  size_t curveSize, Point3D* curve, double smallestSeg, 
    size_t* cleanCurveSize, Point3D* cleanCurve);
  void InsertCurvePoint( double _Point[3] );

  /* Methods for performing Topological Attractions */
protected:

#if 0  // do sigms3d - AM
  bool AttactToVertex(mgVtxTop* _vtx, Point3D* point);
  bool AttactToVertex(mgVtxTop* _vtx, Point3D* point, double _tolerance);
  bool AttractToSegment(mgSegment* _seg, Point3D* point);
  bool AttractToSegment(mgSegment* _seg, Point3D* point, double _tolerance);
  bool AttractToTopology(mgPatch2d* _p2d, Point3D* point);
  bool AttractToTopology(mgPatch2d* _p2d, Point3D* point, double _tolerance);
#endif

  /* Variables */
protected:
  /* Tolerance */
  double m_tolerance;

  /* Curve Array */
  size_t m_CurveArraySize;  // Size of CurvePointsArray
  size_t m_CurveArrayIndex;  // CurvePointsArray Current Position
  Point3D* m_CurvePointsArray; // Contiguous array with all points 
  // of all curves created

  /* Multiple Curve Management */
private:
  size_t m_CurvesNumber;  // While creating curves, indicates the current
  // curves number. While iterating over curves,
  // indicates the index of the current curve.
  size_t m_MaxCurves;    // While creating curves, indicates the maximum
  // number of curves CurveSizesArray currently
  // allows. While iterating over curves, indicates
  // the total number of curves created
  size_t* m_CurvesSizesArray;      // Array with size of each curve
  size_t m_PreviousCurveEndIndex; // Index of CurvePointsArray where 
  // the previous curve ends

  /* Inverted Curve (Section) Management */
private:
  int* m_InvCrvStartIdxArray; // Inverted Curve (Section) Start Index Array

  /* File Output */
private:
  FILE* m_output;

};

#endif
